<?php
class Scrobbler
{
  private $err_msg;
  private $username;
  private $password;
  private $challenge;
  private $submit_host;
  private $submit_port;
  private $submit_url;
  private $queued_tracks;
  
  public function __construct($username,$password)
  {
    //echo('construct');
    $this->error_msg = '';
    $this->username = trim($username);
    $this->password = trim($password);
    $this->challenge = '';
    $this->queued_tracks = array();
    $this->handshake();
  }


  public function get_error_msg()
  {
    return $this->error_msg;
  }

  private function handshake()
  {
    $as_socket = @fsockopen('post.audioscrobbler.com', 80, $errno, $errstr, 10);
    if(!$as_socket)
    {
      $this->error_msg = $errstr;
      //echo(__LINE__);
      return false;
    }
    $username = rawurlencode($this->username);
    $get_string = "GET /?hs=true&p=1.1&c=m3a&v=0.1&u=$username HTTP/1.1\r\n";
    fwrite($as_socket, $get_string);
    fwrite($as_socket, "Host: post.audioscrobbler.com\r\n");
    fwrite($as_socket, "Accept: */*\r\n\r\n");
    $buffer = '';
    while(!feof($as_socket))
    {
      $buffer .= fread($as_socket, 8192);
    }
    fclose($as_socket);
    $split_response = preg_split("/\r\n\r\n/", $buffer);
    if(!isset($split_response[1]))
    {
      $this->error_msg = 'Did not receive a valid response';
      //echo(__LINE__);
      return false;
    }
    $response = explode("\n", $split_response[1]);
    if(substr($response[0], 0, 6) == 'FAILED')
    {
      $this->error_msg = substr($response[0], 7);
      //echo(__LINE__);
      return false;
    }
    if(substr($response[0], 0, 7) == 'BADUSER')
    {
      $this->error_msg = 'Invalid Username';
      //echo(__LINE__);
      return false;
    }
    if(substr($response[0], 0, 6) == 'UPDATE')
    {
      $this->error_msg = 'You need to update your client: '
                         .substr($response[0], 7);
      //echo(__LINE__);
      return false;
    }
    if(preg_match('/http:\/\/(.*):(\d+)(.*)/', $response[3], $matches))
    {
      $this->submit_host = $matches[1];
      $this->submit_port = $matches[2];
      $this->submit_url = $matches[3];
    }
    else
    {
      $this->error_msg = 'Invalid POST URL returned, unable to continue';
      return false;
    }
    $this->challenge = $response[2];
    //echo(__LINE__);
    return true;
  }

  public function queue_track($artist, $album, $track, $timestamp, $length)
  {
  //echo('queue');
    $date = gmdate('Y-m-d H:i:s', $timestamp);
    $mydate = date('Y-m-d H:i:s T', $timestamp);
    if($length < 30)
    {
      debug_event('lastfm',"Not queuing track, too short",'5');
      return false;
    }
    $newtrack = array();
    $newtrack['artist'] = $artist;
    $newtrack['album'] = $album;
    $newtrack['track'] = $track;
    $newtrack['length'] = $length;
    $newtrack['time'] = $date;
    $this->queued_tracks[$timestamp] = $newtrack;
    //echo(__LINE__);
    return true;
  }

  public function submit_tracks()
  {
    if(!count($this->queued_tracks))
    {
      $this->error_msg = "No tracks to submit";
      //echo(__LINE__);
      return false;
    }
    ksort($this->queued_tracks);//sort array by timestamp
    $query_str = 'u=' .rawurlencode($this->username)
                      .'&s='.rawurlencode(md5($this->password.$this->challenge))
                      .'&';
    $i = 0;
    foreach($this->queued_tracks as $track)
    {
      $query_str .= "a[$i]=".rawurlencode($track['artist'])."&t[$i]="
                    .rawurlencode($track['track'])."&b[$i]="
                    .rawurlencode($track['album'])."&";
      $query_str .= "m[$i]=&l[$i]="
                 .rawurlencode($track['length'])."&i[$i]="
                 .rawurlencode($track['time'])."&";
      $i++;
    }
    $as_socket = @fsockopen($this->submit_host,$this->submit_port,$errno,$errstr,10);
    if(!$as_socket)
    {
      $this->error_msg = $errstr;
      //echo(__LINE__);
      return false;
    }
    $action = "POST ".$this->submit_url." HTTP/1.0\r\n";
    fwrite($as_socket, $action);
    fwrite($as_socket, "Host: ".$this->submit_host."\r\n");
    fwrite($as_socket, "Accept: */*\r\n");
    fwrite($as_socket, "Content-type: application/x-www-form-urlencoded\r\n");
    fwrite($as_socket, "Content-length: ".strlen($query_str)."\r\n\r\n");
    fwrite($as_socket, $query_str."\r\n\r\n");
    $buffer = '';
    while(!feof($as_socket))
    {
      $buffer .= fread($as_socket, 8192);
    }
    fclose($as_socket);
    $split_response = preg_split("/\r\n\r\n/", $buffer);
    if(!isset($split_response[1]))
    {
      $this->error_msg = 'Did not receive a valid response';
      //echo(__LINE__);
      return false;
    }
    $response = explode("\n", $split_response[1]);
    if(!isset($response[0]))
    {
      $this->error_msg = 'Unknown error submitting tracks'
                        ."\nDebug output:\n".$buffer;
      //echo(__LINE__);
      return false;
    }
    if(substr($response[0], 0, 6) == 'FAILED')
    {
      $this->error_msg = $response[0];
      //echo(__LINE__);
      return false;
    }
    if(substr($response[0], 0, 7) == 'BADAUTH')
    {
      $this->error_msg = 'Invalid username/password';
      //echo(__LINE__);
      return false;
    }
    if(substr($response[0], 0, 2) != 'OK')
    {
      $this->error_msg = 'Unknown error submitting tracks'
                        ."\nDebug output:\n".$buffer;
      //echo(__LINE__);
      return false;
    }
    //echo(__LINE__);
    return true;
  }


}
?>
